package psn.zjk.common.jdk8;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * @author zhangjk
 * @CREATE_TIME 2021/1/18 15:43
 */
public class MySyncImpl {

    static class MySync extends AbstractQueuedSynchronizer {
        private AtomicInteger count;
        private volatile int limit;
        private volatile boolean released;

        public MySync(int limit) {
            this.limit = limit;
            this.count = new AtomicInteger(0);
        }

        @Override
        protected int tryAcquireShared(int ignored) {
            int newCount = count.incrementAndGet();
            if (!released && newCount > limit) {
                releaseShared(0);
                return 1;
            }
            return -1;
        }

        @Override
        protected boolean tryReleaseShared(int ignored) {
            count.set(0);
            return true;
        }

        public int get() {
            return count.get();
        }
    }

    static class MyCountDownLatch {
        MySync mySync;


        public MyCountDownLatch(int count) {
            mySync = new MySync(count);
        }

        public void countDown() {
            mySync.acquireShared(1);
            System.out.println(1);
        }

        public void countUp() throws InterruptedException {
            mySync.acquireSharedInterruptibly(1);
            System.out.println(1);
        }

    }

    public static void main(String[] args) {
        MyCountDownLatch myCountDownLatch = new MyCountDownLatch(3);
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        executorService.execute(() -> {
            myCountDownLatch.countDown();
        });
        executorService.execute(() -> {
            myCountDownLatch.countDown();
        });
        executorService.execute(() -> {
            myCountDownLatch.countDown();
        });
    }


}